﻿namespace VIT.BusinessLogicLayer
{
    using System.Collections.Generic;
    using System.Linq;

    using VIT.DataAccessLayer;
    using VIT.DataTransferObjects.Presentation;
    using VIT.Library;
    using VIT.Library.Web;

    public class LinkBLL : BLLBase
    {
        private readonly ILinkLanguageDAL _linkLanguageDAL;
        private readonly ICategoryLanguageDAL _categoryLanguageDAL;

        private readonly string _imagePath;
        private readonly string _domainStore;

        #region Constructor
        public LinkBLL(string connectionString = "")
            : base(connectionString)
        {
            this._linkLanguageDAL = new LinkLanguageDAL(this.DatabaseFactory);
            this._categoryLanguageDAL = new CategoryLanguageDAL(this.DatabaseFactory);

            this._imagePath = SettingsManager.AppSettings.LinkImagePath;
            this._domainStore = SettingsManager.AppSettings.DomainStore;
        }
        #endregion

        #region Function
        public List<DataSimpleDto> GetDataSimple(int companyId, string languageId, int categoryId, bool inChildCat, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._linkLanguageDAL.GetAll()
                .Where(e => e.Link.Item.CompanyId == companyId && e.LanguageId == languageId && e.Link.Item.IsPublished && !e.Link.Item.HasDeleted);
                
            if (categoryId > 0)
            {
                IList<int> listCategory;
                if (inChildCat)
                {
                    var categorys = this._categoryLanguageDAL.GetAllIncludeItem()
                        .Where(cat => cat.Category.Item.IsPublished && cat.LanguageId == languageId)
                        .Select(cat => new CategorySimpleDto
                        {
                            ID = cat.CategoryId,
                            Title = cat.Title,
                            ParentId = cat.Category.ParentId
                        }).ToList();

                    listCategory = this.GetAllChildId(categorys, categoryId);
                }
                else
                {
                    listCategory = new List<int>();
                }

                listCategory.Add(categoryId);
                query = query.Where(c => listCategory.Contains(c.Link.CategoryId ?? 0));
            }

            var selected = query.OrderBy(e => e.Link.Item.Orders)
                .ThenByDescending(e => e.Link.Item.CreateDate)
                .Select(a => new DataSimpleDto
                    {
                        Id = a.LinkId,
                        CategoryId = a.Link.CategoryId ?? 0,
                        Title = a.Title,
                        Description = a.Description,
                        ImagePath = a.Link.ImageAvatar,
                        URL = a.Link.URL,
                    });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._imagePath, companyId);
            foreach (var item in data)
            {
                var seo = URL.LinkSEOs.FirstOrDefault(e => e.Url == item.URL.ToLower());
                if (seo != null) item.URL = seo.SeoUrl;

                item.ImagePath = this.VirtualPath(imagePathThumb, item.ImagePath);
            }

            return data;
        }

        public IList<LinkDto> GetLinks(int companyId, string language, int categoryId = 0, int top = 0)
        {
            var query = this._linkLanguageDAL.GetAllIncludeItem()
                .Where(c => c.Link.Item.HasDeleted == false && c.Link.Item.IsPublished && c.Link.Item.CompanyId == companyId && c.LanguageId == language);

            if (categoryId > 0) query = query.Where(e => e.Link.CategoryId == categoryId);

            var links = query.OrderBy(o => o.Link.Item.Orders).ThenByDescending(o => o.LinkId)
                .Select(c => new LinkDto
                  {
                    URL = c.Link.URL,
                    Target = c.Link.Target,
                    Title = c.Title,
                    Description = c.Description,
                    ImagePath = c.Link.ImageAvatar,
                  });

            if (top > 0) links = links.Take(top);

            var data = links.ToList();

            var imagePath = string.Format(this._imagePath, companyId);
            foreach (var item in data)
            {
                var seo = URL.LinkSEOs.FirstOrDefault(e => e.Url == item.URL.ToLower());
                if (seo != null) item.URL = seo.SeoUrl;

                item.ImagePath = this.VirtualPath(imagePath, item.ImagePath);
            }

            return data;
        }
        #endregion

        #region Private method

        /// <summary>
        /// The get all child id.
        /// </summary>
        /// <param name="category">
        /// The category.
        /// </param>
        /// <param name="parentId">
        /// The parent id.
        /// </param>
        /// <returns>
        /// List Category Id 
        /// </returns>
        private IList<int> GetAllChildId(IList<CategorySimpleDto> category, int? parentId)
        {
            var subcats = category.Where(o => o.ParentId == parentId).ToList(); // lay tat ca con cua parentID

            var result = new List<int>();
            foreach (var subcat in subcats)
            {
                if (subcat != null)
                {
                    var temp = this.GetAllChildId(category, subcat.ID);

                    result.Add(subcat.ID);
                    if (temp != null && temp.Count > 0)
                    {
                        result.AddRange(temp);
                    }
                }
            }

            return result;
        }

        private string VirtualPath(string folderPath, string fileName)
        {
            return string.IsNullOrEmpty(fileName) ? string.Empty : string.Format("{0}{1}{2}", this._domainStore, folderPath, fileName);
        }
        #endregion
    }
}